package org.flown.util.mq;


import jakarta.jms.*;
import org.springframework.jms.core.JmsTemplate;

import java.util.HashMap;


/**
 * 使用ConnectionFactory来初始化
 * <p>
 * <bean name="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
 *     <property name="connectionFactory">
 *         <bean class="org.apache.activemq.ActiveMQConnectionFactory">
 *             <property name="brokerURL" value="tcp://192.168.125.87:61616"/>
 *             <property name="userName" value="admin"/>
 *             <property name="password" value="admin"/>
 *             <property name="trustAllPackages" value="true"/>
 *         </bean>
 *     </property>
 *     <property name="maxConnections" value="20"/>
 * </bean>
 * <p>
 * <bean name="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
 *     <property name="targetConnectionFactory" ref="pooledConnectionFactory"/>
 *     <property name="sessionCacheSize" value="5"/>
 * </bean>
 * <p>
 * <bean id="SpringActiveMQUtil" class="org.flown.util.mq.SpringActiveMQUtil">
 *     <property name="ConnectionFactory" ref="cachingConnectionFactory"/>
 * </bean>
 * <p>
 *
 * 使用JmsTemplate来初始化
 * <bean id="JMSTemplate" class="org.springframework.jms.core.JmsTemplate">
 *     <property name="ConnectionFactory" ref="cachingConnectionFactory"/>
 * </bean>
 * <p>
 * <bean id="SpringActiveMQUtil" class="org.flown.util.mq.SpringActiveMQUtil">
 *     <property name="JmsTemplate" ref="JMSTemplate"/>
 * </bean>
 *
 * <br>Message监听器使用 @JmsListener
 */
public class SpringMQUtil
{
    private static JmsTemplate JMS_TEMPLATE;
    private static Connection CONNECTION;
    private static Session SESSION;
    private static final HashMap<String, Destination> DESTINATIONS = new HashMap<>();


    public void setJMSTemplate(JmsTemplate jms_template)
            throws JMSException
    {
        SpringMQUtil.JMS_TEMPLATE = jms_template;
        SpringMQUtil.JMS_TEMPLATE.setDestinationResolver(new DestinationResolver());//设置destination解析器
        ConnectionFactory factory = SpringMQUtil.JMS_TEMPLATE.getConnectionFactory();
        if (factory == null)
            throw new NullPointerException("ConnectionFactory is null");
        SpringMQUtil.CONNECTION = factory.createConnection();
        SpringMQUtil.CONNECTION.start();
        SpringMQUtil.SESSION = SpringMQUtil.CONNECTION.createSession(false, Session.AUTO_ACKNOWLEDGE);
    }
    public void serConnectionFactory(ConnectionFactory factory) throws JMSException {this.setJMSTemplate(new JmsTemplate(factory));}


    public static void close()
    {
        try {
            SpringMQUtil.SESSION.close();
            SpringMQUtil.CONNECTION.close();
        }
        catch (JMSException e) {throw new RuntimeException(e);}
    }


    public static JmsTemplate getJmsTemplate() {return SpringMQUtil.JMS_TEMPLATE;}
    public static Destination getDestination(String destination_name)
    {
        Destination d = SpringMQUtil.DESTINATIONS.get(destination_name);
        if (d == null)
            throw new NullPointerException("Destination is null");
        return d;
    }


    public static void createQueueDestination(String name)
            throws JMSException
    {
        SpringMQUtil.DESTINATIONS.put(name, SpringMQUtil.SESSION.createQueue(name));
    }
    public static void createTopicDestination(String name)
            throws JMSException
    {
        SpringMQUtil.DESTINATIONS.put(name, SpringMQUtil.SESSION.createTopic(name));
    }


    public static Message receiveMessage(String destination_name)
    {
        Destination d = SpringMQUtil.DESTINATIONS.get(destination_name);
        if (d == null)
            throw new NullPointerException("Destination is null");
        return SpringMQUtil.JMS_TEMPLATE.receive(d);
    }


    private static void send(Destination destination, Message message)
    {
        SpringMQUtil.JMS_TEMPLATE.send(destination, session -> message);
    }


    public static void send(String destination_name, Message message)
    {
        Destination d = SpringMQUtil.DESTINATIONS.get(destination_name);
        if (d == null)
            throw new NullPointerException("Destination is null");
        SpringMQUtil.send(d, message);
    }

}


class DestinationResolver implements org.springframework.jms.support.destination.DestinationResolver
{
    @Override
    public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) {
        return SpringMQUtil.getDestination(destinationName);
    }
}













